{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 134,
   "metadata": {},
   "outputs": [],
   "source": [
    "from tensorflow.keras import Sequential\n",
    "from tensorflow.keras import Model\n",
    "from tensorflow.keras.layers import Conv2D, MaxPool2D\n",
    "from tensorflow.keras.layers import Activation\n",
    " \n",
    "import matplotlib.pyplot as plt\n",
    "from pylab import *\n",
    "\n",
    "from PIL import Image\n",
    "import numpy as np\n",
    "\n",
    "import pprint\n",
    "\n",
    "np.set_printoptions(threshold=np.inf)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 150,
   "metadata": {},
   "outputs": [],
   "source": [
    "path=r\"C:\\Users\\mym\\Desktop\\文件接收柜\\feiji_rgb2.jpg\"\n",
    "im = Image.open(path)\n",
    "img=np.array(im)\n",
    "print('输入图shape：',img.shape)\n",
    "print('输入图：',img)\n",
    "# img=img.reshape(img.shape[0],img.shape[1],1)\n",
    "# img=np.expand_dims(img,-1)\n",
    "# print('输入图shape：',img.shape)\n",
    "# print('输入图：',img)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 151,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 转换图片格式\n",
    "img_chanel=[]\n",
    "for item in range(img.shape[-1]):\n",
    "    arr=img[:,:,item]\n",
    "    print('第%s个通道'%item)\n",
    "#     print(arr)\n",
    "    pprint.pprint(arr)\n",
    "    img_chanel.append(arr)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 152,
   "metadata": {},
   "outputs": [],
   "source": [
    "# img_batch = np.expand_dims(img, axis=0)\n",
    "img_input=img.reshape(1,img.shape[0],img.shape[1],img.shape[2],)\n",
    "print(img_input.shape)\n",
    "print(img_input)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 138,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"sequential_6\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "conv2d_6 (Conv2D)            (None, 12, 12, 2)         152       \n",
      "_________________________________________________________________\n",
      "max_pooling2d_6 (MaxPooling2 (None, 3, 3, 2)           0         \n",
      "=================================================================\n",
      "Total params: 152\n",
      "Trainable params: 152\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "\n",
    "model = Sequential()\n",
    "# 第一层CNN\n",
    "# 第一个参数是卷积核的数量，第二三个参数是卷积核的大小\n",
    "model.add(Conv2D(2, (5, 5), input_shape=img.shape))\n",
    "# model.add(Activation('relu'))\n",
    "model.add(MaxPool2D(pool_size=(4, 4)))\n",
    "\n",
    "# 第二层CNN\n",
    "#     model.add(Conv2D(9, (5, 5), input_shape=img_shape))\n",
    "#     model.add(Activation('relu'))\n",
    "#     model.add(MaxPool2D(pool_size=(3, 3)))\n",
    "\n",
    "#     # # # 第三层CNN\n",
    "#     model.add(Conv2D(9, (5, 5), input_shape=img_shape))\n",
    "#     model.add(Activation('relu'))\n",
    "#     model.add(MaxPool2D(pool_size=(2, 2)))\n",
    "\n",
    "#     # # # 第四层CNN\n",
    "#     model.add(Conv2D(9, (3, 3), input_shape=img_shape))\n",
    "#     model.add(Activation('relu'))\n",
    "#     model.add(MaxPool2D(pool_size=(2, 2)))\n",
    "model.summary()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 153,
   "metadata": {},
   "outputs": [],
   "source": [
    "#获取卷积层的卷积核心的值\n",
    "# 注意：卷积核的形状是(5, 5, 3, 4)，与灰度图不同，\n",
    "w,b = model.layers[0].get_weights()\n",
    "\n",
    "print(\"权重 shape：\",w.shape)\n",
    "print(\"偏置量 shape\",b.shape)\n",
    "\n",
    "print(\"权重 ：\",w)\n",
    "print(\"偏置量 \",b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 154,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "# 转换权重形状\n",
    "w_list=[]\n",
    "for item in range(w.shape[-1]):\n",
    "    \n",
    "    print('第%s个卷积核权重'%item)\n",
    "    for item2 in range(w.shape[-2]):\n",
    "        print('--第%s个通道权重'%item2)\n",
    "        result=w[:,:,item2,item]\n",
    "        print(result.shape)\n",
    "#         print(result)\n",
    "        pprint.pprint(result)\n",
    "        w_list.append(result)\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 145,
   "metadata": {},
   "outputs": [],
   "source": [
    "#取某一层的输出为输出新建为model，采用函数模型\n",
    "out_model = Model(inputs=model.input,outputs=[model.layers[0].output,model.layers[1].output])\n",
    "\n",
    "# 输出特征图\n",
    "out_img = out_model.predict(img_batch)\n",
    "\n",
    "print (\"特征图 shape：\",out_img[0].shape)\n",
    "print (\"特征图：\\n\",out_img)\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 142,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "def get_row_col(num_pic):\n",
    "    squr = num_pic ** 0.5\n",
    "    row = round(squr)\n",
    "    col = row + 1 if squr - row > 0 else row\n",
    "    return row, col\n",
    "    \n",
    "def show_img(out_img):\n",
    "    print(\"out_img type::\",type(out_img))\n",
    "    num_pic = out_img.shape[-1]\n",
    "    row, col = get_row_col(num_pic)\n",
    "    print('row,col',row,col)\n",
    "\n",
    "    print('out_img.shape:',out_img.shape)\n",
    "    # print('out_img:',out_img)\n",
    "\n",
    "    #显示将特征图\n",
    "    for _ in range(num_pic):\n",
    "            show_img = out_img[:, :, :, _]\n",
    "    #         print(show_img)\n",
    "            show_img=show_img.reshape(out_img.shape[1:3])\n",
    "            plt.subplot(row, col, _ + 1)\n",
    "            plt.imshow(show_img, cmap='gray')\n",
    "            # plt.imshow(show_img)\n",
    "            plt.axis('off')\n",
    "            print('结果图像shape：：',show_img.shape)\n",
    "            print('结果图像-----')\n",
    "#             print(show_img)\n",
    "            pprint.pprint(show_img)\n",
    "\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 155,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "show_img(out_img[0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 157,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 验证RGB图卷积过程\n",
    "# 将图片3个通道，与一个卷积核的3个通道做乘法运算，然后再求和，与卷积层结果的第一个元素相同（小数点后5位可能有误差）\n",
    "\n",
    "sum_result=np.zeros([5,5])\n",
    "for item in range(3):\n",
    "    img_result=img_chanel[item][:5,:5]\n",
    "    print(img_result)\n",
    "    print(w_list[item])\n",
    "    sum_result+=img_result*w_list[item]\n",
    "\n",
    "print(\"结果\",sum(sum(sum_result)))\n",
    "\n",
    "    "
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
